

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>

#include <sys/epoll.h>
#include <fcntl.h>

#define C100K 1
#define BENCHMARKING 1

#if BENCHMARKING
struct timeval tv_begin;
#define TIME_SUB_MS(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000)
#endif

#define BUFFER_LENGTH       1024
#define DEFAULT_PORT        2048
#define MAX_EPOLL_EVENTS    1024

#define ZEPPEVENT_NEW       0x000
#define ZEPPEVENT_EXSIT     0x001
#define ZEPPEVENT_ISSOCKET  0x003

typedef int (*CALLBACK)(int fd, uint32_t event, void *arg);

struct zeppevent {
    int fd;
    uint32_t events;

    void *arg;
    CALLBACK  callback;

    short status;  // 0 新建 1 已存在 3 sockfd
    char buffer[BUFFER_LENGTH];
    ssize_t length;
    long last_active;
};

struct eventblock {
    struct eventblock *next;
    struct zeppevent *events;
};

struct zeppreactor {
    int epfd;
#if C100K
    int blkcnt;
    struct eventblock *evblk;
#else
    struct zeppevent *events;
#endif
};

int accept_cb(int fd, uint32_t events, void *arg);
int recv_cb(int fd, uint32_t events, void *arg);
int send_cb(int fd, uint32_t events, void *arg);

void zeppevent_set(struct zeppevent *ev, int fd, CALLBACK callback, void *arg);
int zeppevent_add(int epfd, uint32_t events, struct zeppevent *ev);
int zeppevent_del(int epfd, struct zeppevent *ev);

int zeppreactor_run(struct zeppreactor *reactor);
int zeppreactor_addlistener(struct zeppreactor *reactor, int sockfd, CALLBACK callback);
int zeppreactor_init(struct zeppreactor *reactor);
void zeppreactor_destory(struct zeppreactor *reactor);
#if C100K
int zeppreactor_alloc(struct zeppreactor *reactor);
struct zeppevent *zeppreactor_idx(struct zeppreactor *reactor, int sockfd);
#endif

int init_socket(int port);